#pragma once
#include "Locks.h"

#if !defined _DELEGATE_H_
#define _DELEGATE_H_

#define DECLARE_EVENT(varname,class,argtype)	\
	typedef bool (class::*##varname##_EVENT_HANDLER)(argtype*);\
	hxc::Event<##varname##_EVENT_HANDLER , class> varname;

namespace hxc
{

template<typename T, class BaseClass>
class Event
{
	Event(const Event& e){}
public:
	Event():m_pInstance(nullptr)
	{
	}

	explicit Event(BaseClass* p)
	{
		m_pInstance = p;
	}

	~Event()
	{
		
	}

	template<typename FuncType>
	void operator+=(FuncType value)
	{
		m_Lock.Enter();
		m_HandlerArray.push_back(static_cast<T>(value));
		m_Lock.Leave();
	}

	template<typename FuncType>
	void operator-=(FuncType value)
	{
		m_Lock.Enter();
		for (auto Iterator = Array.begin(); Iterator != Array.end(); Iterator++)
		{
			if (*Iterator == static_cast<T>(value))
			{
				m_HandlerArray.erase(Iterator);
				break;
			}
		}
		m_Lock.Leave();
	}

	template<typename ArgType>
	void operator()(ArgType* pe)
	{
		m_Lock.Enter();
		for (auto Iterator = m_HandlerArray.begin(); Iterator != m_HandlerArray.end(); Iterator++)
		{
			T h = *Iterator;
			if ((m_pInstance->*h)(pe))
                break;
		}
		m_Lock.Leave();
	}

	BaseClass* m_pInstance;
private:
	hxc::Critical_Section m_Lock;
	std::vector<T> m_HandlerArray;
};

};//namespace hxc
#endif//if !defined _DELEGATE_H_